﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Configuration;

using ElCharro01.Models;
using ElCharro01.Helpers;

namespace ElCharro01.Areas.Admin.Controllers
{
    public class OrderController : Controller
    {
        private Entities db = new Entities();

        //[Authorize(Roles = "Administrator")]
        public ViewResult Index(string orderedBy = null)
        {
            //riempio la string che verrà visualizzata nel combobox per l'ordinamento
            List<string> OrderBy = new List<String>();
            OrderBy.Add("Seleziona un Ordinamento");
            OrderBy.Add("Stato Spedizione");
            OrderBy.Add("Stato Pagamento");
            OrderBy.Add("Più Recenti");

            ViewBag.OrdPossibility = OrderBy;

            if (orderedBy == "Stato Spedizione")
                return View(db.OrderSet.OrderBy(o => o.ConfermaSpedizione).Where(o => o.ConfermaPagamento == false || o.ConfermaSpedizione == false).ToList());
            else if (orderedBy == "Stato Pagamento")
                return View(db.OrderSet.OrderBy(o => o.ConfermaPagamento).Where(o => o.ConfermaPagamento == false || o.ConfermaSpedizione == false).ToList());
            else if (orderedBy == "Più Recenti")
                return View(db.OrderSet.OrderBy(o => o.DataOrdine).Where(o => o.ConfermaPagamento == false || o.ConfermaSpedizione == false).ToList());
            else
                return View(db.OrderSet.OrderBy(o => o.DataOrdine).Where(o => o.ConfermaPagamento == false || o.ConfermaSpedizione == false).ToList());



        }


        public ActionResult StoredOrder()
        {
            return View(db.OrderSet.OrderBy(o => o.DataOrdine).Where(o => o.ConfermaPagamento == true && o.ConfermaSpedizione == true).ToList());
        }

        public ActionResult PaymentConfirmed(bool confirmed, int OrderID)
        {

            Order Order = db.OrderSet.Single(o => o.Id == OrderID);
            bool succeded;
            //se l'ordine viene confermato aumento il bonus accumulato dal cliente ed eventualmente dal suo reclutatore
            if (confirmed)
            {
                try
                {
                    succeded = SendPaymentConfirmationMail(Order.Id);
                    //aumento il bonus del reclutatore
                    if (Order.Customer.Reclutatore != null)
                    {

                        Order.Customer.Reclutatore.Bonus = Order.Customer.Reclutatore.Bonus + (Order.Totale / 100) * 5;
                        db.ObjectStateManager.ChangeObjectState(Order.Customer.Reclutatore, EntityState.Unchanged);
                        db.UserSet.Attach(Order.Customer.Reclutatore);
                        db.ObjectStateManager.ChangeObjectState(Order.Customer.Reclutatore, EntityState.Modified);
                        db.SaveChanges();

                    }

                    //aumento il bonus del cliente
                    Order.Customer.Bonus = Order.Customer.Bonus + (Order.Totale / 100) * 5;
                    db.ObjectStateManager.ChangeObjectState(Order.Customer, EntityState.Unchanged);
                    db.UserSet.Attach(Order.Customer);
                    db.ObjectStateManager.ChangeObjectState(Order.Customer, EntityState.Modified);
                    db.SaveChanges();
                }
                catch (Exception ex)
                {
                    succeded = false;
                }
            }

                //se l'ordine viene deconfermato sottraggo il bonus che avevo aggiunto
            else
            {
                try
                {
                    succeded = SendPaymentDeconfirmationMail(Order.Id);
                    //diminuisco il bonus del reclutatore
                    if (Order.Customer.Reclutatore != null)
                    {
                        Order.Customer.Reclutatore.Bonus = Order.Customer.Reclutatore.Bonus + (Order.Totale / 100) * 5;
                        db.ObjectStateManager.ChangeObjectState(Order.Customer.Reclutatore, EntityState.Unchanged);
                        db.UserSet.Attach(Order.Customer.Reclutatore);
                        db.ObjectStateManager.ChangeObjectState(Order.Customer.Reclutatore, EntityState.Modified);
                        db.SaveChanges();

                    }

                    //diminuisco il bonus del cliente
                    Order.Customer.Bonus = Order.Customer.Bonus - (Order.Totale / 100) * 5;
                    db.ObjectStateManager.ChangeObjectState(Order.Customer, EntityState.Unchanged);
                    db.UserSet.Attach(Order.Customer);
                    db.ObjectStateManager.ChangeObjectState(Order.Customer, EntityState.Modified);
                    db.SaveChanges();
                }
                catch (Exception ex)
                {
                    succeded = false;
                }
            }

            Order.ConfermaPagamento = confirmed;
            db.ObjectStateManager.ChangeObjectState(Order, EntityState.Unchanged);
            db.OrderSet.Attach(Order);
            db.ObjectStateManager.ChangeObjectState(Order, EntityState.Modified);
            db.SaveChanges();



            //controll se devo reindirizzare a StoredOrder oppure all'Index
            if (Order.ConfermaPagamento == false && Order.ConfermaSpedizione == true)

                return RedirectToAction("StoredOrder", "Order", new { area = "Admin" });
            else
                return RedirectToAction("Index", "Order", new { area = "Admin" });


        }

        public bool SendPaymentConfirmationMail(int orderId)
        {
            Order Order = db.OrderSet.Single(o => o.Id == orderId);
            List<DetailOrder> DetailOrderList = Order.Detail.ToList();
            List<string> OrderedVariants = new List<String>();

            /*aggiungo in OrderedVariants una stringa per ogni variante ordinato contenente il nome del prodotto
             * correlato a quella variante e la quantità ordinata*/
            //aggiorno le quantità disponibili nel magazzino
            foreach (DetailOrder detailOrder in DetailOrderList)
            {
                OrderedVariants.Add("<br />" + "Nome Prodotto: " +
                    detailOrder.Variant.Product.Nome + "<br />" +
                    "Colore: " + detailOrder.Variant.Colore + "<br />" +
                    "Taglia: " + detailOrder.Variant.Taglia + "<br />" +
                    "Quantità: " + detailOrder.Quantita + "<br />");
            }

            string ConcatenatedOrderdVariants = "";
            foreach (string prodottoOrdinato in OrderedVariants)
            {
                ConcatenatedOrderdVariants = ConcatenatedOrderdVariants + prodottoOrdinato;
            }

            try
            {
                String message = "<h3>Conferma Pagamento." + "</h3><br />"
                                + "E' stato confermato il pagamento per il tuo ordine effettuato in data: "
                                + Order.DataOrdine.Day + "/" + Order.DataOrdine.Month + "/" + Order.DataOrdine.Year + " <br />"
                                + "I prodotti ordinati in tale data sono:" + " <br />"
                                + ConcatenatedOrderdVariants + "<br />"
                                + "Prezzo Totale Comprese Le Spese di Spedizione: " + Order.Totale + "<br />"
                                + "<h3>Dati Relativi Alla Spedizione:</h3>" + "<br />"
                                + "Nazione: " + Order.Location.Nazione + "<br />"
                                + "Città: " + Order.Location.Indirizzo + "<br />"
                                + "Cap: " + Order.Location.CodicePostale + "<br />"
                                + "Indirizzo: " + Order.Location.Indirizzo;

                /* Send Mail */
                MailHelper.SendMailMessage(Order.Customer.Email,
                                           "",
                                           "",
                                           "Conferma Pagamento" + System.Configuration.ConfigurationManager.AppSettings["Title"],
                                           message,
                                          ConfigurationManager.AppSettings["Email"]);
            }

            catch (Exception ex)
            {
                return false;
            }

            return true;

        }

        public bool SendPaymentDeconfirmationMail(int orderId)
        {
            Order Order = db.OrderSet.Single(o => o.Id == orderId);
            List<DetailOrder> DetailOrderList = Order.Detail.ToList();
            List<string> OrderedVariants = new List<String>();

            /*aggiungo in OrderedVariants una stringa per ogni variante ordinato contenente il nome del prodotto
             * correlato a quella variante e la quantità ordinata*/
            //aggiorno le quantità disponibili nel magazzino
            foreach (DetailOrder detailOrder in DetailOrderList)
            {
                OrderedVariants.Add("<br />" + "Nome Prodotto: " +
                    detailOrder.Variant.Product.Nome + "<br />" +
                    "Colore: " + detailOrder.Variant.Colore + "<br />" +
                    "Taglia: " + detailOrder.Variant.Taglia + "<br />" +
                    "Quantità: " + detailOrder.Quantita + "<br />");
            }

            string ConcatenatedOrderdVariants = "";
            foreach (string prodottoOrdinato in OrderedVariants)
            {
                ConcatenatedOrderdVariants = ConcatenatedOrderdVariants + prodottoOrdinato;
            }

            try
            {
                String message = "<h3>Deconferma Pagamento" + "</h3><br />"
                                + "E' stato deconfermato il pagamento per il tuo ordine effettuato in data: "
                                + Order.DataOrdine.Day + Order.DataOrdine.Month + Order.DataOrdine.Year + " <br />"
                                + "I prodotti ordinati in tale data sono:" + " <br />"
                                + ConcatenatedOrderdVariants + "<br />";


                /* Send Mail */
                MailHelper.SendMailMessage(Order.Customer.Email,
                                           "",
                                           "",
                                           "Deconferma Pagamento",
                                           message,
                                          ConfigurationManager.AppSettings["Email"]);
            }

            catch (Exception ex)
            {
                return false;
            }

            return true;

        }

        public bool SendShipmentConfirmationMail(int orderId)
        {
            Order Order = db.OrderSet.Single(o => o.Id == orderId);
            List<DetailOrder> DetailOrderList = Order.Detail.ToList();
            List<string> OrderedVariants = new List<String>();

            /*aggiungo in OrderedVariants una stringa per ogni variante ordinato contenente il nome del prodotto
             * correlato a quella variante e la quantità ordinata*/
            foreach (DetailOrder detailOrder in DetailOrderList)
            {
                OrderedVariants.Add("<br />" + "Nome Prodotto: " +
                    detailOrder.Variant.Product.Nome + "<br />" +
                    "Colore: " + detailOrder.Variant.Colore + "<br />" +
                    "Taglia: " + detailOrder.Variant.Taglia + "<br />" +
                    "Quantità: " + detailOrder.Quantita + "<br />");
            }

            string ConcatenatedOrderdVariants = "";
            foreach (string prodottoOrdinato in OrderedVariants)
            {
                ConcatenatedOrderdVariants = ConcatenatedOrderdVariants + prodottoOrdinato;
            }

            try
            {
                String message = "<h3>Avvenuta Spedizione" + "</h3><br />"
                                + "E' stata effettuata la spedizione per il tuo ordine effettuato in data: "
                                + Order.DataOrdine.Day + "/" + Order.DataOrdine.Month + "/" + Order.DataOrdine.Year + " <br />"
                                + "I prodotti ordinati in tale data sono:" + " <br />"
                                + ConcatenatedOrderdVariants + "<br />"
                                + "<h3>Dati Relativi Alla Spedizione:</h3>" + "<br />"
                                + "Nazione: " + Order.Location.Nazione + "<br />"
                                + "Città: " + Order.Location.Indirizzo + "<br />"
                                + "Cap: " + Order.Location.CodicePostale + "<br />"
                                + "Indirizzo: " + Order.Location.Indirizzo + "<br />"
                                + "Puoi controllare lo stato della tua spedizione all'indirizzo: " + 
                                "http://as777.bartolini.it/vas/sped_numspe_par.htm?lang=it" + 
                                " inserendo il tuo Numero Spedizione: " + Order.CodiceSpedizione + "<br />";


                /* Send Mail */
                MailHelper.SendMailMessage(Order.Customer.Email,
                                           "",
                                           "",
                                           "Avvenuta Spedizione",
                                           message,
                                          ConfigurationManager.AppSettings["Email"]);
            }

            catch (Exception ex)
            {
                return false;
            }

            return true;

        }

        public bool SendShipmentDeconfirmationMail(int orderId)
        {
            Order Order = db.OrderSet.Single(o => o.Id == orderId);
            List<DetailOrder> DetailOrderList = Order.Detail.ToList();
            List<string> OrderedVariants = new List<String>();

            /*aggiungo in OrderedVariants una stringa per ogni variante ordinato contenente il nome del prodotto
             * correlato a quella variante e la quantità ordinata*/
            foreach (DetailOrder detailOrder in DetailOrderList)
            {
                OrderedVariants.Add("<br />" + "Nome Prodotto: " +
                    detailOrder.Variant.Product.Nome + "<br />" +
                    "Colore: " + detailOrder.Variant.Colore + "<br />" +
                    "Taglia: " + detailOrder.Variant.Taglia + "<br />" +
                    "Quantità: " + detailOrder.Quantita + "<br />");
            }

            string ConcatenatedOrderdVariants = "";
            foreach (string prodottoOrdinato in OrderedVariants)
            {
                ConcatenatedOrderdVariants = ConcatenatedOrderdVariants + prodottoOrdinato;
            }

            try
            {
                String message = "<h3>Deconferma Spedizione" + "</h3><br />"
                                + "La informiamo che la spedizione per il suo ordine effettuato in data: "
                                + Order.DataOrdine.Day + "/" + Order.DataOrdine.Month + "/" + Order.DataOrdine.Year + " <br />"
                                + " contrariamente a quanto le è stato comunicato via mail, non è ancora stata effettuata." + " <br />"
                                + "I prodotti ordinati in tale data sono:" + " <br />"
                                + ConcatenatedOrderdVariants + "<br />";


                /* Send Mail */
                MailHelper.SendMailMessage(Order.Customer.Email,
                                           "",
                                           "",
                                           "Deconferma Spedizione",
                                           message,
                                          ConfigurationManager.AppSettings["Email"]);
            }

            catch (Exception ex)
            {
                return false;
            }

            return true;

        }

        public ActionResult Delete(int id)
        {
            Order Order = db.OrderSet.Single(o => o.Id == id);
            return View(Order);
        }
        [HttpPost]
        public ActionResult DeleteConfirmed(int id)
        {
            Order Order = db.OrderSet.Single(v => v.Id == id);
            //se l'ordine viene cancellato prima che sia stata confermata la spedizione ed il pagamento
            //vuol dire che c'è stato un problama con l'user e le quantità in stock vanno riprisinate, altrimenti si sta semplicemente 
            //cancellando un ordine in quanto vecchio e non più di interesse
            if (Order.ConfermaSpedizione == false)
            {
                UpdateInstock(id);
            }
            db.OrderSet.DeleteObject(Order);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        public void UpdateInstock(int id)
        {
            Order Order = db.OrderSet.Single(o => o.Id == id);
            List<DetailOrder> DetailOrderList = Order.Detail.ToList();

            //aggiorno le quantità disponibili nel magazzino
            foreach (DetailOrder detailOrder in DetailOrderList)
            {
                Variant Variant = new Variant();
                Variant = detailOrder.Variant;
                Variant.InStock = Variant.InStock + detailOrder.Quantita;
                db.ObjectStateManager.ChangeObjectState(Order, EntityState.Unchanged);
                db.OrderSet.Attach(Order);
                db.ObjectStateManager.ChangeObjectState(Order, EntityState.Modified);
                db.SaveChanges();
            }
        }

        public ActionResult ShipmentCodeInsert(bool confirmed, int OrderID)
        {
            ViewBag.OrderID = OrderID;
            ViewBag.Confirmed = confirmed;
            return View();
        }

        [HttpPost]
        public ActionResult ShipmentConfirmed(bool confirmed, int OrderID, string ShipmentNumber)
        {
            Order Order = db.OrderSet.Single(o => o.Id == OrderID);
            bool succeded;

            //salvo il cambiamento dello stato di ConfermaSpedizione
            Order.ConfermaSpedizione = confirmed;
            Order.CodiceSpedizione = ShipmentNumber;
            db.ObjectStateManager.ChangeObjectState(Order, EntityState.Unchanged);
            db.OrderSet.Attach(Order);
            db.ObjectStateManager.ChangeObjectState(Order, EntityState.Modified);
            db.SaveChanges();

            if (confirmed)
            {
                try
                {
                    succeded = SendShipmentConfirmationMail(Order.Id);
                }
                catch (Exception ex)
                {
                    succeded = false;
                }
            }
            else
                try
                {
                    succeded = SendShipmentDeconfirmationMail(Order.Id);
                }
                catch (Exception ex)
                {
                    succeded = false;
                }

     

            //controll se devo reindirizzare a StoredOrder oppure all'Index
            if (Order.ConfermaPagamento == true && Order.ConfermaSpedizione == false)

                return RedirectToAction("StoredOrder", "Order", new { area = "Admin" });
            else
                return RedirectToAction("Index", "Order", new { area = "Admin" });


            return Redirect("Index");


        }

        protected override void Dispose(bool disposing)
        {

            db.Dispose();
            base.Dispose(disposing);
        }
    }
}